#include <iostream>
#include <assert.h>
#include <map>
#include <sstream>
#include <vector>
#include <list>
#include <set>
#include "serialize.h"

class MyTest
{ 
public:
    MyTest(){}
    MyTest(int age, const std::string& name):p(new int(age)),name(name){}

    friend void Serialize(std::ostream & os, const MyTest& val)
    {
        Serialize(os, *val.p);
        Serialize(os, val.name);
    }
    friend void Deserialize(std::istream & is, MyTest& val) 
    {
        val.p = new int;
        Deserialize(is, *val.p);
        Deserialize(is, val.name);
    }
    int *p;
    std::string name; 
};



void print(const std::string& msg)
{
    //反序列化
    std::istringstream iss(msg);
    std::vector<std::string> d;
    Deserialize(iss, d);

    for(auto item : d)
    {
        std::cout << item << std::endl;
    }
    int val;
    Deserialize(iss, val);
    std::cout << "-->" << val << std::endl;

	std::string str;
	Deserialize(iss, str);
	std::cout << "-->" << str << std::endl;

	std::list<int> s;
	Deserialize(iss, s);
	for (auto item : s)
	{
		std::cout << item << std::endl;
	}

	std::map<std::string, int> m;
	Deserialize(iss, m);
	for (auto item : m)
	{
		std::cout << item.first << "-->" << item.second << std::endl;
	}

	std::tuple<int, std::string, double> tp;
	Deserialize(iss, tp);
	std::cout << std::get<0>(tp) << "-->" << std::get<1>(tp) << "-->" << std::get<2>(tp) << std::endl;

	std::set<int> st;
	Deserialize(iss, st);
	for (auto item : st)
	{
		std::cout << item << std::endl;
	}
    
    std::vector<MyTest> vecVal;
    Deserialize(iss, vecVal);

    for(auto item : vecVal)
    {
        std::cout << "age:" << *item.p << "  name:" << item.name << std::endl;
    }
}


int main()
{
    //序列化
	std::vector<std::string> d = { "10","20","50","100","1000" };
    std::ostringstream oss;
    Serialize(oss, d);

    Serialize(oss, 10);

	//Serialize(oss, "world");

	std::string str("hello");
	Serialize(oss, str);


	std::list<int> s = { 10,20,50,100,1000 }; 
	Serialize(oss, s);

	std::map<std::string, int> val = { { "1",3 }, { "3",4 }, {"6",8} };
	Serialize(oss, val);


	std::tuple<int, std::string, double> tp{ 0, "test", 1.3 };
	Serialize(oss, tp);

    std::vector<MyTest> vecVal = {MyTest(35, "hello"), MyTest(40, "world")}; 

	std::set<int> st = { 100,30,70 };
	Serialize(oss, st);

    Serialize(oss, vecVal);

    print(oss.str());
    return 0;
}